package io;

import model.Player;

public final class ActionSender {
    private Player p;

    public ActionSender(Player p) {
        this.p = p;
    }

    public void update() {
        p.out().addOpcodeVarShort(1);
        if (p.didTeleport()) {
            p.out().addByte(1);
            p.out().addShort(p.x());
            p.out().addShort(p.y());
        } else if (p.walkDir() != -1) {
            p.out().addByte(2);
            p.out().addByte(p.walkDir());
        } else {
            p.out().addByte(0);
        }
        if (p.hasUpdate()) {
            p.out().addByte(1);
            int mask = 0;
            if (p.chatUpdate()) {
                mask |= 0x1;
            }
            if (p.appearanceUpdate()) {
                mask |= 0x2;
            }
            p.out().addByte(mask);
            if (p.chatUpdate()) {
                p.out().addString(p.chat());
            }
            if (p.appearanceUpdate()) {
                p.out().addByte(p.headId());
                p.out().addByte(p.torsoId());
                p.out().addByte(p.legsId());
            }
        } else {
            p.out().addByte(0);
        }
        for (int i = 0; i < p.players().size(); i++) {
            Player p2 = p.players().get(i);
            if (!p.withinDistance(p2)) {
                p.out().addByte(1);
                p.players().remove(i--);
            } else if (p2.walkDir() != -1) {
                p.out().addByte(2);
                p.out().addByte(p2.walkDir());
            } else {
                p.out().addByte(0);
            }
            if (p2.hasUpdate() && p.withinDistance(p2)) {
                p.out().addByte(1);
                int mask = 0;
                if (p2.chatUpdate()) {
                    mask |= 0x1;
                }
                if (p2.appearanceUpdate()) {
                    mask |= 0x2;
                }
                p.out().addByte(mask);
                if (p2.chatUpdate()) {
                    p.out().addString(p2.chat());
                }
                if (p2.appearanceUpdate()) {
                    p.out().addByte(p2.headId());
                    p.out().addByte(p2.torsoId());
                    p.out().addByte(p2.legsId());
                }
            } else {
                p.out().addByte(0);
            }
        }
        for (Player p2 : p.world().players()) {
            if (!p.players().contains(p2) && p.withinDistance(p2)) {
                p.players().add(p2);
                p.out().addByte(p2.x() - p.x());
                p.out().addByte(p2.y() - p.y());
                p.out().addString(p2.username());
                int mask = 0;
                if (p2.chatUpdate()) {
                    mask |= 0x1;
                }
                //if (p2.appearanceUpdate()) {
                    mask |= 0x2;
                //}
                p.out().addByte(mask);
                if (p2.chatUpdate()) {
                    p.out().addString(p2.chat());
                }
                //if (p2.appearanceUpdate()) {
                    p.out().addByte(p2.headId());
                    p.out().addByte(p2.torsoId());
                    p.out().addByte(p2.legsId());
                //}
            }
        }
        p.out().addByte(127);
        p.out().endOpcodeVarShort();
        if (p.regionUpdate()) {
            p.out().addOpcode(2);
            p.out().addShort(p.regionX());
            p.out().addShort(p.regionY());
        }
    }
}